package com.chat.websocket.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.chat.websocket.entity.dto.SearchUserDTO;
import com.chat.websocket.entity.enums.DeleteStatus;
import com.chat.websocket.entity.enums.FileFolder;
import com.chat.websocket.entity.enums.GlobalConstants;
import com.chat.websocket.entity.enums.UserStatus;
import com.chat.websocket.entity.module.User;
import com.chat.websocket.entity.vo.LoginVO;
import com.chat.websocket.entity.vo.SearchUserVO;
import com.chat.websocket.entity.vo.UserVO;
import com.chat.websocket.exception.GlobalException;
import com.chat.websocket.exception.UserException;
import com.chat.websocket.mapper.UserMapper;
import com.chat.websocket.service.UserService;
import com.chat.websocket.util.ip2region.Ip2regionUtil;
import com.chat.websocket.util.minio.MinIOUtil;
import com.chat.websocket.util.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * SunJingxuan
 * 2022 \ 07 \ 29
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

	@Resource
	private UserMapper userMapper;

	@Resource
	private RedisUtil redisUtil;

	@Resource
	private Ip2regionUtil ip2regionUtil;

	@Resource
	private MinIOUtil minIOUtil;

	@Override
	public UserVO passwordLogin(LoginVO loginVO) {
		String userPhone = loginVO.getUserPhone();
		String userPassword = loginVO.getUserPassword();
		String ip = ip2regionUtil.getIp();
		log.info("用户{}ip{}", loginVO.getUserPhone(), ip);
		if (redisUtil.exists(ip)) {
			redisUtil.delete(ip);
		}
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("user_phone", userPhone);
		queryWrapper.eq("user_status", UserStatus.NORMAL.getStatus());
		queryWrapper.eq("delete_status", DeleteStatus.NOT_DELETED.getStatus());
		boolean exists = userMapper.exists(queryWrapper);
		if (exists) {
			queryWrapper.eq("user_password", userPassword);
			User user = userMapper.selectOne(queryWrapper);
			try {
				Optional<User> optionalUser = Optional.of(user);
				UserVO userVO = new UserVO();
				BeanUtils.copyProperties(optionalUser.get(), userVO);
				return userVO;
			} catch (NullPointerException e) {
				throw new UserException(GlobalConstants.USER_PASSWORD_ERR.getCode(), GlobalConstants.USER_PASSWORD_ERR.getMessage());
			}
		}
		throw new UserException(GlobalConstants.USER_NOT_EXIST.getCode(), GlobalConstants.USER_NOT_EXIST.getMessage());
	}

	@Override
	public UserVO verifyCodeLogin(LoginVO loginVO) {
		String userPhone = loginVO.getUserPhone();
		String verifyCode = loginVO.getVerifyCode();
		String ip = ip2regionUtil.getIp();
		log.info("用户{}ip{}", loginVO.getUserPhone(), ip);
		String verifyCodeRed = redisUtil.get(ip).toString();
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("user_phone", userPhone);
		boolean exists = userMapper.exists(queryWrapper);
		if (exists) {
			if (verifyCode.equals(verifyCodeRed)) {
				User user = userMapper.selectOne(queryWrapper);
				Optional<User> optionalUser = Optional.of(user);
				UserVO userVO = new UserVO();
				BeanUtils.copyProperties(optionalUser.get(), userVO);
				return userVO;
			} else {
				throw new UserException(GlobalConstants.USER_VERIFY_CODE_WRONG.getCode(), GlobalConstants.USER_VERIFY_CODE_WRONG.getMessage());
			}
		} else {
			throw new UserException(GlobalConstants.USER_NOT_EXIST.getCode(), GlobalConstants.USER_NOT_EXIST.getMessage());
		}
	}

	@Override
	public List<SearchUserVO> searchUser(SearchUserDTO searchUserDTO) {
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		if (StringUtils.isNotEmpty(searchUserDTO.getUsername())) {
			queryWrapper.like("user_name", searchUserDTO.getUsername()).or().like("user_nickname", searchUserDTO.getUsername());
		}
		queryWrapper.eq("user_status", UserStatus.NORMAL.getStatus()).eq("delete_status", DeleteStatus.NOT_DELETED.getStatus()).notIn("user_id", Collections.singletonList(searchUserDTO.getUserId()));
		boolean exists = userMapper.exists(queryWrapper);
		if (exists) {
			List<User> users = userMapper.selectList(queryWrapper);
			List<SearchUserVO> searchUserVOS = new ArrayList<>();
			users.forEach(item -> {
				SearchUserVO searchUserVO = new SearchUserVO();
				BeanUtils.copyProperties(item, searchUserVO);
				searchUserVOS.add(searchUserVO);
			});
			return searchUserVOS;
		}
		return null;
	}

	@Override
	public UserVO userInfo(Integer userId) {
		UserVO userVO = new UserVO();
		BeanUtils.copyProperties(userMapper.selectById(userId), userVO);
		return userVO;
	}

	@Override
	public String uploadUserHeadImg(MultipartFile img, Integer userId) {
		try {
			String headImgUrl = minIOUtil.uploadFile(img, "public", FileFolder.HEAD_IMG.getFolder());
			User user = new User();
			user.setUserId(userId);
			user.setUserHeadImg(headImgUrl);
			userMapper.updateById(user);
			return headImgUrl;
		} catch (GlobalException e){
			log.error("用户上传头像出错：code:{}, message:{}", e.getCode(), e.getMessage());
			return null;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
